//
// Created by 邹嘉旭 on 2025/8/8.
//

#ifndef LDACS_CORENET_GS1_H
#define LDACS_CORENET_GS1_H

#include "define.h"
#include "ldacs_corenet.h"
#include "util/log.h"

#define GS1_TYP_LEN 4
#define GS1_PKT_HEAD_LEN 2
#define GS1_DATA_HEAD_LEN 3
#define GS1_AS_INI_HEAD_LEN 7

typedef enum {
    GS1_SAC_RQST = 1,
    GS1_SAC_RESP,
    GS1_INIT_AS,
    GS1_SNF_UPLOAD,
    GS1_SNF_DOWNLOAD,
    GS1_KEY_TRANS,
    GS1_HO_REQUEST,
    GS1_HO_REQUEST_ACK,
    GS1_HO_COMPLETE,
    GS1_UP_UPLOAD_TRANSPORT,
    GS1_UP_DOWNLOAD_TRANSPORT,
    GS1_AS_EXIT,
    GS1_DATA_UP,
    GS1_DATA_DOWN,
} GS1_TYPE;

#define GS1_TYPE_MAX GS1_DATA_DOWN

#pragma pack(1)

typedef struct gs1_sac_rqst_s {
    uint8_t TYPE;
    uint32_t AS_UA;
} gs1_sac_rqst_t;

extern struct_desc_t gs1_sac_rqst_desc;

typedef struct gs1_sac_resp_s {
    uint8_t TYPE;
    uint32_t AS_UA;
    uint16_t AS_SAC;
} gs1_sac_resp_t;

extern struct_desc_t gs1_sac_resp_desc;

typedef struct gs1_initial_as_t {
    uint8_t TYPE;
    uint16_t AS_SAC;
    uint32_t AS_UA;
    uint16_t GS_SAC;
    buffer_t *sdu;
} gs1_init_as_t;
extern struct_desc_t gs1_init_as_desc;

static void free_gs1_init_as(void *args) {
    gs1_init_as_t *init = args;
    if (init) {
        if (init->sdu) {
            free_buffer(init->sdu);
        }
        free(init);
    }
}

typedef struct gs1_snf_pkt_t {
    uint8_t TYPE;
    uint16_t AS_SAC;
    buffer_t *sdu;
} gs1_snf_pkt_t;
extern struct_desc_t gs1_snf_pkt_desc;

static void free_gs1_snf_pkt(void *args) {
    gs1_snf_pkt_t *upload = args;
    if (upload) {
        if (upload->sdu) {
            free_buffer(upload->sdu);
        }
        free(upload);
    }
}

typedef struct gs1_as_exit_s {
    uint8_t TYPE;
    uint16_t AS_SAC;
} gs1_as_exit_t;
extern struct_desc_t gs1_as_exit_desc;

typedef struct gs1_data_s {
    uint8_t VER;
    uint16_t AS_SAC;
    uint8_t IDTF;
    buffer_t *sdu;
} gs1_data_t;
extern struct_desc_t gs1_data_desc;

static void free_gs1_data(void *args) {
    gs1_data_t *data = args;
    if (data) {
        if (data->sdu) {
            free_buffer(data->sdu);
        }
        free(data);
    }
}

typedef struct gs1_ho_rqst_s {
    uint8_t VER;
    uint16_t AS_SAC;
    uint16_t GSS_SAC;
    uint16_t GST_SAC;
} gs1_ho_rqst_t;
extern struct_desc_t gs1_ho_rqst_desc;


typedef struct gs1_ho_rqst_ack_s {
    uint8_t TYPE;
    uint16_t AS_SAC;
    uint16_t NEXT_CO;
} gs1_ho_rqst_ack_t;
extern struct_desc_t gs1_ho_rqst_ack_desc;

typedef struct gs1_ho_complete_s {
    uint8_t TYPE;
    uint16_t AS_SAC;
    uint16_t GS_SAC;
} gs1_ho_complete_t;
extern struct_desc_t gs1_ho_complete_desc;


#pragma pack()

extern size_t gs1_format_count;
extern cn_format_desc_t gs1_format_descs[];


#endif //LDACS_CORENET_GS1_H